package 数据结构专栏.简单级别;

/**
 * @DESC https://leetcode-cn.com/problems/search-insert-position/
 * @Author tzq
 * @Date 2020-03-30 20:26
 **/
public class _35_搜索插入位置 {
    public static void main(String[] args) {
        int[] nums = new int[]{1, 3, 5};
//        System.out.println(searchInsert(nums, 5));
        System.out.println(searchInsert2(nums, 4));
//        System.out.println(searchInsert(nums, 7));
    }

    /**
     * 二分搜索
     *
     * @param nums
     * @param target
     * @return
     */
    public static int searchInsert(int[] nums, int target) {
        int left = 0, right = nums.length - 1;

        while (left <= right) {
            int mid = (left + right) / 2;
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] < target) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }

        return left;
    }

    /**
     * 优化
     *
     * @param nums
     * @param target
     * @return
     */
    public static int searchInsert2(int[] nums, int target) {
        int left = 0, right = nums.length - 1;
        if (nums[right]< target) return nums.length;
        while (left <= right) {
            // 防止整形溢出，得到一个负数
            int mid = left + (right - left) / 2;
            if (nums[mid] == target) {
                return mid;
                // 严格小于 target 的元素一定不是解
            } else if (nums[mid] < target) {
                // 下一轮搜索区间是 [mid + 1, right]
                left = mid + 1;
            } else {
                right = mid - 1; // 搜索区间：[left,mid-1]
            }
        }

        return left;
    }


    /**
     * 另外的写法
     * https://leetcode-cn.com/problems/search-insert-position/solution/te-bie-hao-yong-de-er-fen-cha-fa-fa-mo-ban-python-/
     * @param nums
     * @param target
     * @return
     */
    public int searchInsert3(int[] nums, int target) {
        int len = nums.length;
        if (len == 0) {
            return 0;
        }

        int left = 0;
        // 因为有可能数组的最后一个元素的位置的下一个是我们要找的，故右边界是 len
        int right = len;

        while (left < right) {
            int mid = (left + right) >>> 1;
            // 小于 target 的元素一定不是解
            if (nums[mid] < target) {
                // 下一轮搜索的区间是 [mid + 1, right]
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return left;
    }


    /**
     * 另外的解法2
     * @param nums
     * @param target
     * @return
     */
    public int searchInsert4(int[] nums, int target) {
        int len = nums.length;
        if (len == 0) {
            return 0;
        }

        int left = 0;
        int right = len;

        while (left < right) {
            int mid = (left + right) >>> 1;
            if (nums[mid] < target) {
                // 下一轮搜索区间是 [mid + 1, right]
                left = mid + 1;
            } else if (nums[mid] == target) {
                // 根据本题特殊性，看到等于 target 的元素，返回任意一个即可
                return mid;
            } else {
                right = mid;
            }
        }
        return left;
    }






}
